package cn.bugstack.infrastructure.adapter.port;


import cn.bugstack.domain.auth.adapter.port.ILoginPort;
import cn.bugstack.infrastructure.gateway.IWeixinApiService;
import cn.bugstack.infrastructure.gateway.dto.WeixinQrCodeRequestDTO;
import cn.bugstack.infrastructure.gateway.dto.WeixinQrCodeResponseDTO;
import cn.bugstack.infrastructure.gateway.dto.WeixinTemplateMessageDTO;
import cn.bugstack.infrastructure.gateway.dto.WeixinTokenResponseDTO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import retrofit2.Call;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 丨一
 * @version 1.0
 * @title LoginPortImpl
 * @description:
 * @date 2024/11/12 13:51
 */

import lombok.extern.slf4j.Slf4j;


@Slf4j
@Component
public class LoginPort implements ILoginPort {


    @Value("${weixin.config.app-id}")
    private String appid;

    @Value("${weixin.config.app-secret}")
    private String appSecret;
    
    @Value("${weixin.config.template-id}")
    private String template_id;
    
//    //加入缓存
//    @Resource
//    private Cache<String, String> weixinAccessToken;
//
//    @Resource
//    private Cache<String, String> openidToken;

    @Resource
    private RedisTemplate<String,String> redisTemplate;
    
    @Resource
    private IWeixinApiService weixinApiService;
    
    
    @Override
    public String createQrCodeTicket() throws Exception {
//        String accessToken = weixinAccessToken.getIfPresent(appid);
        String accessToken = redisTemplate.opsForValue().get(appid);
        if (accessToken == null) {
            //accessToken 为空
            //1.发送请求获取 accessToken
            Call<WeixinTokenResponseDTO> call = weixinApiService.getAccessToken("client_credential", appid, appSecret);
            WeixinTokenResponseDTO resBody = call.execute().body();
            //断言
            assert resBody != null;
            accessToken = resBody.getAccess_token();
            //2.存到 cache 中 -> 多实例用 redis,这里用 guava cache
            //weixinAccessToken.put(appid, accessToken);

            // redis
            redisTemplate.opsForValue().setIfAbsent(appid,accessToken,2, TimeUnit.HOURS);
        }
        //3.构建WeixinQrCodeReq类型 -> 设置 ticket 的属性
        WeixinQrCodeRequestDTO weixinQrCodeReq = WeixinQrCodeRequestDTO.builder()
                .action_name(WeixinQrCodeRequestDTO.ActionNameTypeVO.QR_SCENE.getCode())
                .action_info(WeixinQrCodeRequestDTO.ActionInfo.builder()
                        .scene(WeixinQrCodeRequestDTO.ActionInfo.Scene.builder()
                                .scene_id(100601)
                                .build())
                        .build())
                .expire_seconds(2592000)
                .build();
        //4. 创建qrCode
        WeixinQrCodeResponseDTO qrBody = weixinApiService.createQrCode(accessToken, weixinQrCodeReq).execute().body();
        assert qrBody != null;
        return qrBody.getTicket();
    }


    @Override
    public String checkLogin(String ticket) {
        return redisTemplate.opsForValue().get(ticket);
    }

    @Override
    public void saveLoginState(String ticket, String openid) {
        redisTemplate.opsForValue().setIfAbsent(ticket,openid,1,TimeUnit.HOURS);
    }

    @Override
    public void sendLoginTemplate(String openid) throws IOException {
        // 1. 获取 accessToken 【实际业务场景，按需处理下异常】
        String accessToken = redisTemplate.opsForValue().get(appid);
        if (null == accessToken){
            Call<WeixinTokenResponseDTO> call = weixinApiService.getAccessToken("client_credential", appid, appSecret);
            WeixinTokenResponseDTO weixinTokenResponseDTO = call.execute().body();
            assert weixinTokenResponseDTO != null;
            accessToken = weixinTokenResponseDTO.getAccess_token();
            redisTemplate.opsForValue().set(appid,accessToken,1,TimeUnit.HOURS);
        }

        // 2. 发送模板消息
        Map<String, Map<String, String>> data = new HashMap<>();
        WeixinTemplateMessageDTO.put(data, WeixinTemplateMessageDTO.TemplateKey.USER, openid);

        WeixinTemplateMessageDTO templateMessageDTO = new WeixinTemplateMessageDTO(openid, template_id);
        templateMessageDTO.setUrl("https://gaga.plus");
        templateMessageDTO.setData(data);

        Call<Void> call = weixinApiService.sendMessage(accessToken, templateMessageDTO);
        call.execute();
    }


}
